package model

import (
	"bytes"
	"database/sql/driver"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"math"
	"reflect"
)

type Point struct {
	X float64 `json:"lat"`
	Y float64 `json:"lng"`
}

func (p *Point) Value() (driver.Value, error) {
	if p != nil {
		buf := new(bytes.Buffer)
		fmt.Fprintf(buf, "SRID=4326;POINT(%.6f %.6f)", p.X, p.Y)
		//fmt.Printf("Point Value %v \n", buf.Bytes())

		return string(buf.Bytes()), nil
	}
	return "", nil
}

func (p *Point) String() string {
	return fmt.Sprintf("%v, %v", p.X, p.Y)
}

func (p *Point) Scan(val interface{}) (err error) {

	if bb, ok := val.(string); ok {

		x := bb[18:34]
		y := bb[34:]
		//		fmt.Printf("all: %s, x: %s, y:%s \n", bb, x, y)
		p.X = bytesToFloat64(x)
		p.Y = bytesToFloat64(y)

	} else {
		fmt.Println(reflect.TypeOf(val))
		panic("error")
	}
	return nil
}

func bytesToFloat64(b string) float64 {
	s1, err := hex.DecodeString(b)
	if err != nil {
		fmt.Printf("string :%s\n", b)
		panic(err)
	}

	bits := binary.LittleEndian.Uint64(s1)
	return math.Float64frombits(bits)
}
